package cn.com.cifi.mars.web.action.price;

import cn.com.cifi.mars.bean.vo.price.*;
import cn.com.cifi.mars.bean.vo.price.req.PriceWarPlanReqParam;
import cn.com.cifi.mars.common.base.BaseAction;
import cn.com.cifi.mars.common.bean.R;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.StageStatusEnum;
import cn.com.cifi.mars.constant.VersionCreateEnum;
import cn.com.cifi.mars.constant.VersionTypeEunm;
import cn.com.cifi.mars.constant.WhetherEnum;
import cn.com.cifi.mars.entity.MdmStage;
import cn.com.cifi.mars.entity.PriceVersion;
import cn.com.cifi.mars.entity.ProjectLockRecordDetail;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.service.*;
import cn.com.cifi.mars.service.impl.ProjectLockRecordDetailServiceImpl;
import cn.com.cifi.mars.service.transfer.PriceVersionValueTransferService;
import cn.com.cifi.mars.util.StrUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
public class PriceMgrController extends BaseAction implements IPriceMgrController {

    private static final Logger logger = LoggerFactory.getLogger(PriceMgrController.class);

    @Autowired
    private PriceVersionService priceVersionService;
    @Autowired
    private StageService stageService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private PriceVersionValueOrgService priceVersionValueOrgService;
    @Autowired
    private PriceVersionValueTransferService priceVersionValueTransferService;
    @Autowired
    private ProjectLockRecordDetailServiceImpl projectLockRecordDetailServiceImpl;

    @Override
    public R<String> createPriceVersion(String apiVersion, String projectFid, String versionType) {
        IdmUser operator = getOperator();
        String key = Constants.PRICE_CREATE_VERSION_LOCK + versionType+ "_" + projectFid;
        //禁止重复创建
        if (!redisTemplate.opsForValue().setIfAbsent(key, 1, 180, TimeUnit.SECONDS)) {
            throw new MsgException(CodeEnum.SYS_EXISTENT);
        }
        try {
            if (versionType != null && StringUtils.isNotEmpty(versionType.trim()) && versionType.equals(VersionTypeEunm.INVESTMENT.getKey())) {
                return ok(priceVersionValueOrgService.createSysCastDecisionVersion(projectFid, VersionCreateEnum.MANUALCREATE.getKey(), operator, null, null));
            } else if (versionType != null && StringUtils.isNotEmpty(versionType.trim()) && versionType.equals(VersionTypeEunm.WARPLAN.getKey())) {
                return ok(priceVersionValueOrgService.createSysDynamicVersion(projectFid, VersionTypeEunm.WARPLAN.getKey(), VersionCreateEnum.MANUALCREATE.getKey(), operator, null, null, null, null));
            } else if (versionType != null && StringUtils.isNotEmpty(versionType.trim()) && versionType.equals(VersionTypeEunm.GETPRICE.getKey())) {
                return ok(priceVersionValueOrgService.createSysDynamicVersion(projectFid, VersionTypeEunm.GETPRICE.getKey(), VersionCreateEnum.MANUALCREATE.getKey(), operator, null, null,null, null));
            } else if (versionType != null && StringUtils.isNotEmpty(versionType.trim()) && versionType.equals(VersionTypeEunm.DYNAMIC.getKey())){
                return ok(priceVersionValueOrgService.createSysDynamicVersion(projectFid, VersionTypeEunm.DYNAMIC.getKey(), VersionCreateEnum.MANUALCREATE.getKey(), operator, null, null,null, null));
            } else {
                throw new MsgException(CodeEnum.NON_TYPE_VERSIONS);
            }
        }finally {
            redisTemplate.delete(key);
        }
    }

    @Override
	public R<String> createBatchAdjustPriceVersion(String apiVersion, String projectFid, String versionType) {
    	IdmUser operator = getOperator();
    	if(!versionType.equals(VersionTypeEunm.DYNAMIC.getKey())) {
    		throw new MsgException(CodeEnum.NON_TYPE_VERSIONS);
    	}
    	String  versionId = priceVersionValueOrgService.createSysDynamicVersion(projectFid,versionType, VersionCreateEnum.MANUALCREATE.getKey(), operator, null, null,null,WhetherEnum.YES.getKey());
		return ok(versionId);
	}

	@Override
    public R<PriceVersionListVO> getPriceVersionList(String apiVersion, String projectFid, String versionType) {
        return ok(priceVersionService.getPriceVersionInfo(projectFid, versionType));
    }

    @Override
    public R<PriceSelectItemVO> getPriceVersion(String apiVersion, String versionId) {
        return ok(priceVersionService.getPriceCastDecisionVersion(versionId));
    }

    @Override
    public R<PriceVersionListVO> priceVersionDetail(String apiVersion, String versionId) {
        return ok(priceVersionService.priceVersionDetail(versionId));
    }

    @Override
    public R<String> deletePriceVersion(String apiVersion, String versionId) {
        String alias = getOperator().getAlias();
        priceVersionService.deletePriceVersion(versionId, alias);
        return ok();
    }

    @Override
    public R saveWarPlanPriceVersion(String apiVersion, PriceWarPlanReqParam priceWarPlanReqParam) {
        String alias = getOperator().getAlias();
        String key = Constants.PRICE_UPDATE_VERSION_LOCK + priceWarPlanReqParam.getVersionId();
        //禁止重复创建
        if (!redisTemplate.opsForValue().setIfAbsent(key, 1, 180, TimeUnit.SECONDS)) {
            throw new MsgException(CodeEnum.SYS_EXISTENT);
        }
        try {
            if(priceWarPlanReqParam.getVersionType().equals(VersionTypeEunm.INVESTMENT.getKey())){
                priceVersionService.savePriceCastDecisionVersion(priceWarPlanReqParam, alias);
            }else{
                priceVersionService.saveWarPlanPriceVersion(priceWarPlanReqParam, alias);
            }
        }finally{
            redisTemplate.delete(key);
        }
        return ok();
    }

    @Override
    public R<PriceCompareBasicInfoVO> priceVersionCompareBasicInfo(String apiVersion, String projectId, List<String> versionTypes) {
        return ok(priceVersionService.priceVersionCompareBasic(projectId, versionTypes));
    }

    @Override
    public R<List<ApprovedDiffDetailVO>> priceVersionCompare(String apiVersion, List<PriceCompareVersionIdsVO> priceCompareVersionIdsVOs) {
        return ok(priceVersionService.priceVersionCompare(priceCompareVersionIdsVOs));
    }

    @Override
    public R<DifferenceReviewVersionVO> valueDifferenceReview(String apiVersion, String code, List<PriceCompareVersionIdsVO> priceCompareVersionIdsVOs) {
        return ok(priceVersionService.valueDifferenceReview(code, priceCompareVersionIdsVOs));
    }

    @Override
    public R priceVersionAssessmentLable(String apiVersion, String versionId) {
        priceVersionService.priceVersionAssessmentLable(versionId);
        return ok();
    }

    @Override
    public R<String> priceVersionValidated(String apiVersion, String versionId) {
        return ok(priceVersionService.priceVersionValidated(versionId));
    }

    @Override
    public R priceVersionUpdateState(String apiVersion, List<String> versionIds, String versionState) {
        String alias = getOperator().getAlias();
        if (CollectionUtils.isNotEmpty(versionIds)){
            priceVersionService.updateStateById(versionIds, versionState, alias);
        }
        return ok();
    }

    @Override
    public R<PriceNewestVersion> priceNewestVersion(String apiVersion, String projectFid) {
        return ok(priceVersionService.priceNewestVersion(projectFid));
    }

    @Override
    public R<Map<String, String>> priceVersionTransfer(String apiVersion) {
        priceVersionValueTransferService.priceVersionTransfer();
        return ok();
    }

    @Override
    public R<Map<String, String>> priceFinalizationToProjectAndTime(String apiVersion, String stageId, String finalizationTime) {
        priceVersionService.priceFinalizationToProjectAndTime(stageId, finalizationTime);
        return ok();
    }

    @Override
    public void priceExcelExport(String apiVersion, HttpServletRequest request, HttpServletResponse response, String versionId) {
        priceVersionService.priceExcelExport(versionId, request, response);
    }

    @Override
    public R<String> exceptionPriceVersion(String apiVersion, String projectFid, String versionType) {
        IdmUser operator = getOperator();
        String key = Constants.PRICE_CREATE_VERSION_LOCK + versionType+ "_" + projectFid;
        //禁止重复创建
        if (!redisTemplate.opsForValue().setIfAbsent(key, 1, 180, TimeUnit.SECONDS)) {
            throw new MsgException(CodeEnum.SYS_EXISTENT);
        }
        try {
            if (versionType != null && StringUtils.isNotEmpty(versionType.trim()) && versionType.equals(VersionTypeEunm.INVESTMENT.getKey())) {
                return ok(priceVersionValueOrgService.createSysCastDecisionVersion(projectFid, VersionCreateEnum.EXCEPTIONCREATE.getKey(), operator, 5, null));
            } else if (versionType != null && StringUtils.isNotEmpty(versionType.trim()) && versionType.equals(VersionTypeEunm.WARPLAN.getKey())) {
                return ok(priceVersionValueOrgService.createSysDynamicVersion(projectFid, VersionTypeEunm.WARPLAN.getKey(), VersionCreateEnum.EXCEPTIONCREATE.getKey(), operator, 5, null, null, null));
            } else {
                throw new MsgException(CodeEnum.NON_TYPE_VERSIONS);
            }
        }finally {
            redisTemplate.delete(key);
        }
    }

    /**
     * 版本解锁
     * @param versionId 版本id
     * @param msg 解锁报文
     */
    @Override
    public void modifyNoticeByVersionId(String apiVersion, String versionId, String msg) {
        LocalDateTime now = LocalDateTime.now();
        //解析json
        JSONObject requestData = JSON.parseObject(msg);
        JSONObject requestEsbInfo = requestData.getJSONObject("esbInfo");
        String instId = requestEsbInfo.getString("instId");
        JSONObject requestInfo = JSONObject.parseObject(requestData.getString("requestInfo"));

        String projectId = requestInfo.getString("projectId");
        String projectCode = requestInfo.getString("projectCode");
        String schemeId = requestInfo.getString("schemeId");
        JSONArray areaItems = requestInfo.getJSONArray("areaItems");

        Set<String> stageIds = new HashSet<String>();
        Set<String> bldPrdIds = new HashSet<String>();
        List<ProjectLockRecordDetail> projectLockRecordDetails = new ArrayList<ProjectLockRecordDetail>();
        Map<String, List<ProjectLockRecordDetail>> stageRecordDetailMap = new HashMap<String, List<ProjectLockRecordDetail>>();
        if (CollectionUtils.isNotEmpty(areaItems)){
            for (int i = 0; i < areaItems.size(); i++) {
                JSONObject areaItem = areaItems.getJSONObject(i);

                ProjectLockRecordDetail projectLockRecordDetail = createLockRecordDeatailInfo(now, projectId, projectCode, schemeId, areaItem);
                projectLockRecordDetails.add(projectLockRecordDetail);

                String stageId = projectLockRecordDetail.getStageId();
                String bldPrdId = projectLockRecordDetail.getBldPrdId();
                stageIds.add(stageId);
                bldPrdIds.add(bldPrdId);

                List<ProjectLockRecordDetail> projectLockRecordDetailsList = stageRecordDetailMap.get(stageId);
                if(CollectionUtils.isEmpty(projectLockRecordDetailsList)){
                    projectLockRecordDetailsList = new ArrayList<ProjectLockRecordDetail>();
                }
                projectLockRecordDetailsList.add(projectLockRecordDetail);
                stageRecordDetailMap.put(stageId, projectLockRecordDetailsList);
            }

            if(CollectionUtils.isNotEmpty(projectLockRecordDetails)){
                try{
                    projectLockRecordDetailServiceImpl.saveBatch(projectLockRecordDetails);
                }catch (Exception e){
                    logger.error("####################     refreshPriceVersion    projectLockRecordDetailService:"+e.getMessage(), e);
                }
            }

            if (CollectionUtils.isNotEmpty(stageIds)){
                for (String stageId : stageIds){
                    Map<String, List<ProjectLockRecordDetail>> projectLockRecordDetailMap = new HashMap<String, List<ProjectLockRecordDetail>>();
                    List<ProjectLockRecordDetail> recordDetails = stageRecordDetailMap.get(stageId);
                    for (ProjectLockRecordDetail projectLockRecordDetail : recordDetails){
                        String bldPrdId = projectLockRecordDetail.getBldPrdId();
                        List<ProjectLockRecordDetail> projectLockRecordDetailList = projectLockRecordDetailMap.get(bldPrdId);
                        if (CollectionUtils.isEmpty(projectLockRecordDetailList)){
                            projectLockRecordDetailList = new ArrayList<ProjectLockRecordDetail>();
                        }
                        projectLockRecordDetailList.add(projectLockRecordDetail);
                        projectLockRecordDetailMap.put(bldPrdId, projectLockRecordDetailList);
                    }

                    //查询指定分期信息
                    MdmStage mdmStage = stageService.selectById(stageId);
                    if(mdmStage == null){
                        throw new MsgException(CodeEnum.STAGE_NON_EXISTENT);
                    }

                    PriceVersion recordPriceVersion = priceVersionService.selectById(versionId);
                    if (recordPriceVersion != null){
                        String versionType = recordPriceVersion.getVersionType();
                        String versionState = recordPriceVersion.getVersionState();

                        projectLockRecordDetailServiceImpl.planValueRecordRefreshOrCreate(instId, now, bldPrdIds, stageId, projectLockRecordDetailMap, mdmStage, recordPriceVersion, versionType, versionState);
                    }
                }
            }
        }
    }

    private ProjectLockRecordDetail createLockRecordDeatailInfo(LocalDateTime now, String projectId, String projectCode, String schemeId, JSONObject areaItem) {
        ProjectLockRecordDetail projectLockRecordDetail = new ProjectLockRecordDetail();
        projectLockRecordDetail.setId(UUIDUtils.create());
        projectLockRecordDetail.setRecordId(UUIDUtils.create());
        projectLockRecordDetail.setSchemeId(schemeId);
        projectLockRecordDetail.setProjectId(projectId);
        projectLockRecordDetail.setProjectCode(projectCode);
        projectLockRecordDetail.setStageId(areaItem.getString("stageId"));
        projectLockRecordDetail.setStageCode(areaItem.getString("stageCode"));
        projectLockRecordDetail.setBldPrdId(areaItem.getString("bldPrdId"));
        projectLockRecordDetail.setIsParking(StrUtils.stringToInteger(areaItem.getString("isParking")));
        projectLockRecordDetail.setName(areaItem.getString("name"));
        projectLockRecordDetail.setType(areaItem.getString("type"));
        projectLockRecordDetail.setNum(StrUtils.stringToInteger(areaItem.getString("num")));
        projectLockRecordDetail.setArea(StrUtils.stringToBigDecimal(areaItem.getString("area")));
        projectLockRecordDetail.setAveragePrice(StrUtils.stringToBigDecimal(areaItem.getString("averagePrice")));
        projectLockRecordDetail.setPrice(StrUtils.stringToBigDecimal(areaItem.getString("price")));
        projectLockRecordDetail.setCreateTime(now);
        projectLockRecordDetail.setUpdateTime(now);
        return projectLockRecordDetail;
    }

    /**
     * 分期最新版本刷新实际数据
     * @param apiVersion
     * @param projectFid
     * @return
     */
    @Override
    public R<String> refreshPriceValueByStageId(String apiVersion, String projectFid) {
    	//查询指定分期信息
        MdmStage mdmStage = stageService.selectById(projectFid);
        if(mdmStage == null){
            throw new MsgException(CodeEnum.STAGE_NON_EXISTENT);
        }else{
            String status = mdmStage.getStatus();
            if (StringUtils.isNotEmpty(status) && status.equals(StageStatusEnum.INACTIVE.getKey())){
                throw new MsgException(CodeEnum.CREATE_STAGE_INACTIVE_ERROR);
            }
        }
        priceVersionValueOrgService.refreshPriceValueByStageId(projectFid);
        return ok();
    }
    

	@Override
	public R<GroupPriceVersionListVO> groupPriceVersionList(String apiVersion, String projectId) {
		List<GroupPriceVersionListVO> list = priceVersionService.selectGroupPriceVersionList(projectId);
		return ok(list);
	}

	@Override
	public R<GroupPriceDetailVO> groupPriceVersion(String apiVersion,String versionId) {
		return ok(priceVersionService.selectGroupPriceVersion(versionId));
	}

	@Override
	public R<String> batchrefreshPriceValue(String apiVersion,String yearmonth, String projectFid, String versionId,String type) {
		priceVersionValueOrgService.batchrefreshPriceValue(yearmonth,projectFid,versionId,type);
		return ok();
	}
    
}
